﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.ApplicationPages;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
using System.IO;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;

namespace MFD.SharePoint.TaskNotification
{
    public class TaskNotificationPage : LayoutsPageBase
    {
        private const string LISTSETTINGS_PAGE = "{0}/_layouts/listedit.aspx?List={1}";
        
        protected DateTimeControl notificationTime;
        protected DropDownList ddlStatusColumn;

        protected InputFormCheckBox enableTaskAboutToStart;
        protected InputFormTextBox taskAboutToStartSubject;
        protected InputFormTextBox taskAboutToStartBody;
        protected DropDownList daysBeforeStartDate;
        protected DropDownList ddlAboutToStartStatusChoice;


        protected InputFormCheckBox enableTaskNotStarted;
        protected InputFormTextBox taskNotStartedSubject;
        protected InputFormTextBox taskNotStartedBody;
        protected DropDownList ddlNotStartedStatusChoice;


        protected InputFormCheckBox enableTaskDue;
        protected InputFormTextBox taskDueSubject;
        protected InputFormTextBox taskDueBody;
        protected DropDownList daysBeforeDueDate;
        protected DropDownList ddlDueStatusChoice;


        protected InputFormCheckBox enableTaskOverDue;
        protected InputFormTextBox taskOverDueSubject;
        protected InputFormTextBox taskOverDueBody;
        protected DropDownList ddlOverdueStatusChoice;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);



           

            for (int i = 1; i <= 5; i++)
                daysBeforeStartDate.Items.Add(new ListItem(i.ToString()));
            for (int i = 1; i <= 5; i++)
                daysBeforeDueDate.Items.Add(new ListItem(i.ToString()));


            //check if there is already a job running and get the settings from it
            string listId = Page.Request.QueryString["listID"];


            SPList list = this.Web.Lists[new Guid(listId)];


            foreach (SPField field in list.Fields)
                if (field is SPFieldChoice)
                    ddlStatusColumn.Items.Add(new ListItem(field.Title, field.InternalName));
               



            Guid featureID = new Guid(TaskNotification.NOTIFICATION_SITE_FEATURE_GUID);
            var obj = this.Site.Features[featureID].Properties;

            SPFeatureProperty prop = obj[listId];
            TaskNotificationConfig cfg = null;

            if (prop!=null)
                cfg = Utils.Deserialize<TaskNotificationConfig>(obj[listId].Value);

            if (cfg != null)
            {
                this.enableTaskAboutToStart.Checked = cfg.EnableTaskAboutToStartNotification;
                this.enableTaskDue.Checked = cfg.EnableTaskDueNotification;
                this.enableTaskNotStarted.Checked = cfg.EnableTaskNotStartedNotification;
                this.enableTaskOverDue.Checked = cfg.EnableTaskOverDueNotification;

                this.taskAboutToStartSubject.Text = cfg.TaskAboutToStartSubject;
                this.taskDueSubject.Text = cfg.TaskDueSubject;
                this.taskNotStartedSubject.Text = cfg.TaskNotStartedSubject;
                this.taskOverDueSubject.Text = cfg.TaskOverDueSubject;

                this.daysBeforeDueDate.SelectedIndex = cfg.DaysBeforeDueDate - 1;
                this.daysBeforeStartDate.SelectedIndex = cfg.DaysBeforeStartDate - 1;

                this.notificationTime.SelectedDate = cfg.NotificationSchedule;


                this.taskAboutToStartBody.Text = cfg.TaskAboutToStartBody;
                this.taskNotStartedBody.Text = cfg.TaskNotStartedBody;
                this.taskDueBody.Text = cfg.TaskDueBody;
                this.taskOverDueBody.Text = cfg.TaskOverDueBody;

                ddlStatusColumn.SelectedIndex = ddlStatusColumn.Items.IndexOf(ddlStatusColumn.Items.FindByValue(cfg.StatusColumnName));

                SetStatusChoices(list, ddlStatusColumn.SelectedItem.Text);

                ddlAboutToStartStatusChoice.SelectedIndex = ddlAboutToStartStatusChoice.Items.IndexOf(ddlAboutToStartStatusChoice.Items.FindByText(cfg.AboutToStartStatusChoice));

                ddlNotStartedStatusChoice.SelectedIndex = ddlNotStartedStatusChoice.Items.IndexOf(ddlNotStartedStatusChoice.Items.FindByText(cfg.NotStartedStatusChoice));

                
                ddlDueStatusChoice.SelectedIndex = ddlDueStatusChoice.Items.IndexOf(ddlDueStatusChoice.Items.FindByText(cfg.DueStatusChoice));

                ddlOverdueStatusChoice.SelectedIndex = ddlOverdueStatusChoice.Items.IndexOf(ddlOverdueStatusChoice.Items.FindByText(cfg.OverdueStatusChoice));

            }
            else
            {
                 ddlStatusColumn.SelectedIndex = ddlStatusColumn.Items.IndexOf(ddlStatusColumn.Items.FindByValue("Status"));

                 SetStatusChoices(list, ddlStatusColumn.SelectedItem.Text);

                this.taskAboutToStartBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskAboutToStartTemplate);
                this.taskDueBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskDueTemplate);
                this.taskNotStartedBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskNotStartedTemplate);
                this.taskOverDueBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskOverDueTemplate);

                
            }

            


            //let's fix the body if it is empty in cfg
            if (string.IsNullOrEmpty(this.taskAboutToStartBody.Text))
                this.taskAboutToStartBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskAboutToStartTemplate);
            if (string.IsNullOrEmpty(this.taskDueBody.Text))
                this.taskDueBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskDueTemplate);
            if (string.IsNullOrEmpty(this.taskNotStartedBody.Text))
                this.taskNotStartedBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskNotStartedTemplate);
            if (string.IsNullOrEmpty(this.taskOverDueBody.Text))
                this.taskOverDueBody.Text = GetTaskNotificationTemplate(TaskNotification.TaskOverDueTemplate);



           // ddlStatusColumn.SelectedIndexChanged += new EventHandler(ddlStatusColumn_SelectedIndexChanged);
        }

        private void SetStatusChoices(SPList list, string statusColumn)
        {
            SPFieldChoice statusField = list.Fields[statusColumn] as SPFieldChoice;
            ddlAboutToStartStatusChoice.DataSource = statusField.Choices;
            ddlAboutToStartStatusChoice.DataBind();
            ddlAboutToStartStatusChoice.SelectedIndex = ddlAboutToStartStatusChoice.Items.IndexOf(ddlAboutToStartStatusChoice.Items.FindByText("Not Started"));

            
            ddlNotStartedStatusChoice.DataSource = statusField.Choices;
            ddlNotStartedStatusChoice.DataBind();
            ddlNotStartedStatusChoice.SelectedIndex = ddlNotStartedStatusChoice.Items.IndexOf(ddlNotStartedStatusChoice.Items.FindByText("Not Started"));

            ddlDueStatusChoice.DataSource = statusField.Choices;
            ddlDueStatusChoice.DataBind();
            ddlDueStatusChoice.SelectedIndex = ddlDueStatusChoice.Items.IndexOf(ddlDueStatusChoice.Items.FindByText("In Progress"));

            ddlOverdueStatusChoice.DataSource = statusField.Choices;
            ddlOverdueStatusChoice.DataBind();
            ddlOverdueStatusChoice.SelectedIndex = ddlOverdueStatusChoice.Items.IndexOf(ddlOverdueStatusChoice.Items.FindByText("Completed"));


        }

        protected void ddlStatusColumn_SelectedIndexChanged(object sender, EventArgs e)
        {
            string listId = Page.Request.QueryString["listID"];

            SPList list = this.Web.Lists[new Guid(listId)];

            SetStatusChoices(list, ddlStatusColumn.SelectedItem.Text);
        }
            
        

        protected void buttonSaveClicked(object sender, EventArgs args)
        {

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SaveNotificationSettings();
            });

            string listId = Page.Request.QueryString["listID"];

            //redirect to list settings page
                string redirectPage = string.Format(LISTSETTINGS_PAGE, this.Web.Url,listId);
                this.Response.Redirect(redirectPage);
                
        }

        protected virtual void buttonCloseClicked(object sender, EventArgs e)
        {
            string sourceUrl = this.Request.QueryString["source"];
            if (!string.IsNullOrEmpty(sourceUrl))
                this.Response.Redirect(sourceUrl);

            using (SPWeb web = SPContext.GetContext(this.Context).Web)
            {
                string listId = Page.Request.QueryString["listID"];

                string redirectPage = string.Format(LISTSETTINGS_PAGE, web.Url,listId);
                this.Response.Redirect(redirectPage);
            }

        }

        private void SaveNotificationSettings()
        {
            SPUtility.ValidateFormDigest();

            //get list Id from the query string
            string listId = Page.Request.QueryString["listID"];

            Guid listIdGuid = new Guid(listId); ;
            
            TaskNotificationConfig cfg = new TaskNotificationConfig();

            
            cfg.DaysBeforeDueDate = Int16.Parse(this.daysBeforeDueDate.SelectedValue);
            cfg.DaysBeforeStartDate = Int16.Parse(this.daysBeforeStartDate.SelectedValue);


            cfg.EnableTaskAboutToStartNotification = this.enableTaskAboutToStart.Checked;
            cfg.EnableTaskDueNotification = this.enableTaskDue.Checked;
            cfg.EnableTaskNotStartedNotification = this.enableTaskNotStarted.Checked;
            cfg.EnableTaskOverDueNotification = this.enableTaskOverDue.Checked;

            

            cfg.ListID = listIdGuid;
            cfg.WebURL = this.Web.ServerRelativeUrl;


            //obj.Update(true);

            

            //Set task notification body
            if (string.IsNullOrEmpty(this.taskAboutToStartBody.Text))
            {
                cfg.TaskAboutToStartBody = GetTaskNotificationTemplate(TaskNotification.TaskAboutToStartTemplate);
            }
            else
                cfg.TaskAboutToStartBody = this.taskAboutToStartBody.Text;
            
            cfg.TaskAboutToStartSubject = this.taskAboutToStartSubject.Text;


            if (string.IsNullOrEmpty(this.taskDueBody.Text))
            {

                cfg.TaskDueBody = GetTaskNotificationTemplate(TaskNotification.TaskDueTemplate);
                
            }
            else
                cfg.TaskDueBody = this.taskDueBody.Text;
            cfg.TaskDueSubject = this.taskDueSubject.Text;


            if (string.IsNullOrEmpty(this.taskNotStartedBody.Text))
            {
                
                    cfg.TaskNotStartedBody = GetTaskNotificationTemplate(TaskNotification.TaskNotStartedTemplate);
                
            }
            else
                cfg.TaskNotStartedBody = this.taskNotStartedBody.Text;
            cfg.TaskNotStartedSubject = this.taskNotStartedSubject.Text;

            if (string.IsNullOrEmpty(this.taskOverDueBody.Text))
            {

                cfg.TaskOverDueBody = GetTaskNotificationTemplate(TaskNotification.TaskOverDueTemplate);
                
            }
            else
                cfg.TaskOverDueBody = this.taskOverDueBody.Text;
            cfg.TaskOverDueSubject = this.taskOverDueSubject.Text;

            
            
            cfg.NotificationSchedule = this.notificationTime.SelectedDate;


            cfg.StatusColumnName = ddlStatusColumn.SelectedValue;

            cfg.NotStartedStatusChoice = ddlNotStartedStatusChoice.SelectedValue;

            cfg.AboutToStartStatusChoice = ddlAboutToStartStatusChoice.SelectedValue;

            cfg.DueStatusChoice = ddlDueStatusChoice.SelectedValue;

            cfg.OverdueStatusChoice = ddlOverdueStatusChoice.SelectedValue;


            
            Guid featureID = new Guid(TaskNotification.NOTIFICATION_SITE_FEATURE_GUID);
            using (SPSite site = new SPSite(this.Site.ID))
            {
                
                var obj = site.Features[featureID].Properties;


                SPFeatureProperty prop = obj[listId];

                string xml = Utils.Serialize(cfg);
                if (prop != null)
                    prop.Value = xml;
                else
                    obj.Add(new SPFeatureProperty(listId, xml));

                obj.Update(); //we persist the feature properties into the Db
            }
        }


        private string GetTaskNotificationTemplate(string templateFile)
        {
            string ret;
            string path = this.Context.Server.MapPath(templateFile);
            using (var reader = new StreamReader(path))
            {

                ret =  reader.ReadToEnd();
            }

            return ret;
        }
    }
}
